home *** CD-ROM | disk | FTP | other *** search
- // refptr.hpp - Macros for RefCntPtrs
- // These macros simplify the process of
- // creating a new reference count pointer
- // class for a new class type - instead of
- // copying an existing one and changing the
- // names with a text editor, the
- // preprocessor is used to substitute the
- // appropriate names. This is basically an
- // attempt to emulate class templates, until
- // C++ compilers that implement templates
- // are available.
- //
- // There are two primary macros here - the
- // first is the DECLARE macro, for the class
- // declaration and inline functions, i.e.
- // the stuff usually found in the ".hpp"
- // file. The DEFINE macro contains the
- // definition of the non-inline member
- // functions - the stuff usually found in
- // the ".cpp" file.
- //
- // To use these, simply create a class
- // derived from RefCntItem, then put a
- // RefCntPtrDECLARE() in an appropriate
- // header file and a RefCntPtrDEFINE() in
- // appropriate definition file (the class
- // name is substituted for 'type').
-
- #ifndef RefCntPtr_MACROS
- #define RefCntPtr_MACROS
-
- // this is used to create a name for
- // the class being defined, by
- // concatenating the original item
- // class name with "RefCntPtr"
- #define RefCntPtr(type) \
- type ## RefCntPtr
-
-
- // If DEBUG is defined, using a zero
- // pointer (an error) results in a
- // message. An exit() statement
- // might also be appropriate.
-
- #ifdef DEBUG
- #include <iostream.h>
- #define RefCntPtrDebug(type) \
- if (0 == p_ptr) \
- cout << "ERROR - using 0 " \
- "RefCntPtr to " #type "\n";
- #else
- #define RefCntPtrDebug(type)
- #endif
-
-
- #define RefCntPtrDECLARE(type) \
- class RefCntPtr(type) \
- { \
- private: \
- \
- type * p_ptr; \
- \
- void p_inc (void); \
- \
- void p_decAndDelete ( \
- type * dest); \
- \
- void p_assign ( \
- type * rVal); \
- public: \
- RefCntPtr(type) (void) \
- : p_ptr(0) {;}; \
- \
- RefCntPtr(type) ( \
- const RefCntPtr(type)& in) \
- : p_ptr (in.p_ptr) \
- { p_inc(); }; \
- \
- RefCntPtr(type) ( \
- type * in) \
- : p_ptr(in) \
- { p_inc(); }; \
- \
- ~RefCntPtr(type) (void) \
- {p_decAndDelete(p_ptr);}; \
- \
- RefCntPtr(type) & operator = ( \
- RefCntPtr(type) & rVal) \
- { p_assign (rVal.p_ptr); \
- return *this; }; \
- \
- RefCntPtr(type) & operator = ( \
- type * rVal) \
- { p_assign (rVal); \
- return *this; }; \
- \
- type * operator -> (void) \
- { RefCntPtrDebug(type) \
- return p_ptr; }; \
- \
- type & operator * (void) \
- { RefCntPtrDebug(type) \
- return *p_ptr; }; \
- \
- /* see note */ \
- operator int (void) \
- {return (p_ptr != 0);}; \
- \
- private: \
- int operator == (RefCntPtr(type)&); \
- int operator != (RefCntPtr(type)&); \
- int operator < (RefCntPtr(type)&); \
- int operator <= (RefCntPtr(type)&); \
- int operator > (RefCntPtr(type)&); \
- int operator >= (RefCntPtr(type)&); \
- };
- // operator int() allows comparisons such as
- // if (ptr) {},
- // which is great. Unfortunately, it also
- // allows comparisons such as
- // if (ptr1 == ptr2) {}
- // to compile, but not as expected
- // - operator int() is first applied to
- // both sides, then the comparison is made
- // with the resulting integers.
- //
- // This behavior can be overridden by
- // declaring operator== - it has precedence
- // here. Since I am working in MS-DOS with
- // its segmented addressing, I didn't want
- // pointer comparisons, (they don't always
- // work) so I made operator== and its
- // companions private. It would be simple
- // to make them public and implement them
- // if needed.
-
-
- #define RefCntPtrDEFINE(type) \
- void RefCntPtr(type)::p_assign( \
- type * rVal) \
- \
- /* the order of the calls to the */ \
- /* increment and decrement functions */ \
- /* is significant here. If the rVal */ \
- /* and current value point to the same */ \
- /* place, we could delete the item and */ \
- /* then discover we need it. */ \
- { \
- type * tmp = p_ptr; \
- p_ptr = rVal; \
- p_inc(); \
- p_decAndDelete(tmp); \
- }; \
- \
- void RefCntPtr(type)::p_inc (void) \
- { \
- if (p_ptr) \
- p_ptr->incRefCnt(); \
- }; \
- \
- void RefCntPtr(type)::p_decAndDelete ( \
- type * dest) \
- { \
- if (dest) \
- { \
- dest->decRefCnt(); \
- if (0 == dest->refCnt()) \
- delete dest; \
- }; \
- };
-
- #endif
-